<?php

class AddPlacement extends DataExtension implements PermissionProvider {
    private static $casting = array(
        'TotalPlacementDirectDownline' => 'Int',
        'TotalPlacementGroupDownline' => 'Int',
        'TotalPlacementLeftGroupDownline' => 'Int',
        'TotalPlacementRightGroupDownline' => 'Int'
    );
	
	function validate(ValidationResult $validationResult) {
		if($this->owner->hasField('SetPlacementUsername')){
			$current_placement = Placement::get()->filter('MemberID', $this->owner->ID)->filter('ParentID', Distributor::get_id_by_username($this->owner->SetPlacementUsername))->count();
			if(!$current_placement){
				$placement = Placement::get()->filter('Member.Username', $this->owner->SetPlacementUsername)->first();
				if(!$placement){
					$subvalid = new ValidationResult();
	        		$subvalid->error(_t('AddPlacement.INVALID_PLACEMENT_USERNAME', 'Invalid placement username'), "INVALID_PLACEMENT_USERNAME");
	        		$validationResult->combineAnd($subvalid);
				}
				else if($this->owner->SetPlacementUsername == $this->owner->Username){
					$subvalid = new ValidationResult();
	        		$subvalid->error(_t('AddPlacement.INVALID_PLACEMENT_OWNSELF', 'Unable to placement ownself'), "PLACEMENT_USERNAME_INVALID");
	        		$validationResult->combineAnd($subvalid);
				}
				else if($this->owner->SetPlacementPosition && Placement::get()->filter('ParentID', $placement->ID)->filter('NSeqno', $this->owner->SetPlacementPosition)->count()){
					$subvalid = new ValidationResult();
	        		$subvalid->error(_t('AddPlacement.POSITION_EXISTS', 'The placement position is already registered by other member'), "POSITION_EXISTS");
	        		$validationResult->combineAnd($subvalid);
				}
				else if($this->owner->Sponsor()->ID){
					$obj = Placement::get()->find('MemberID', $this->owner->Sponsor()->ID);
					$checkPlacement = Placement::get()
		        	->filter('NLeft:GreaterThanOrEqual', (int)$obj->NLeft)
		        	->filter('NRight:LessThanOrEqual', (int)$obj->NRight)
					->filter('MemberID', (int)$this->owner->Placement()->ID)->count();
					if(!$checkPlacement){
						$subvalid = new ValidationResult();
	            		$subvalid->error(_t('AddPlacement.PLACEMENT_NOT_MATCH', 'Placement is not match with the sponsor'), "PLACEMENT_NOT_MATCH");
	            		$validationResult->combineAnd($subvalid);
					}
				}
			}
		}
        
        return $validationResult;
    }
    
    function updateCMSFields(FieldList $fields){
        if(!$this->owner->exists()){
            $fields->insertAfter(PlacementField::create('SetPlacementUsername', _t('AddPlacement.PLACEMENT_USERNAME', 'Placement Username')), 'Username');
        }
        else{
        	if(Permission::check('CHANGE_Placement')){
        		$placement = Placement::get()->find('MemberID', $this->owner->ID);
        		$fields->insertAfter(PlacementField::create('SetPlacementUsername', _t('AddPlacement.PLACEMENT_USERNAME', 'Placement Username'), $this->owner->Placement()->Username, $placement->NSeqno)->setExcludeID($placement->MemberID), 'Username');
        	}
			else{
	            $fields->insertAfter($placement = ReadonlyField::create('PlacementUsername', _t('AddPlacement.PLACEMENT_USERNAME', 'Placement Username'), sprintf('%s - %s (%s)', $this->owner->Placement()->Username, $this->owner->Placement()->getName(), Placement::get()->find('MemberID', $this->owner->ID)->NSeqno)), 'Username');
				$placement->setIncludeHiddenField(true);
			}
        }
    }
    
    function onAfterWrite(){
    	if($this->owner->hasField('SetPlacementUsername') || $this->owner->hasField('SetSponsorUsername')){
	        $root_username = Placement::get_root_username();
	        $placement = Placement::get()->find('MemberID', $this->owner->ID);
			if(!$placement){
				$placement = Placement::create()->setField('MemberID', $this->owner->ID);
			}
			
	        if($this->owner->Username != $root_username){
	        	if($placement->Parent()->Username != $this->owner->SetPlacementUsername && $this->owner->hasField('SetPlacementUsername')){
	                $placement->setPlacement($this->owner->SetPlacementUsername);
	                if($this->owner->hasField('SetPlacementPosition')){
	                    $placement->setPosition($this->owner->SetPlacementPosition);
	                } else if($this->owner->hasField('SetPlacementPositionOption')){
	                    $placement->setPositionOption($this->owner->SetPlacementPositionOption);
	                }
	            }
	            else if(!$placement->exists() && $this->owner->hasField('SetSponsorUsername')){
	                $placement->setPlacement($this->owner->SetSponsorUsername);
	            }
	            $placement->write();
	        }
        }
    }
    
    function Placement(){
		if($this->owner->SetPlacementUsername){
			$obj = Placement::get()->filter('Member.Username', $this->owner->SetPlacementUsername)->first();
			return $obj ? $obj->Member() : Member::create();
		}
		
		$placement = Placement::get()->find('MemberID', $this->owner->ID);
        return ($placement && $placement->ParentID) ? $placement->Parent()->Member() : Member::create();
    }
    
    function getTotalPlacementDirectDownline(){
        $placement = Placement::get()->find('MemberID', $this->owner->ID);
        return ($placement) ? $placement->TotalDirectDownline : 0;
    }
    
    function getTotalPlacementGroupDownline(){
        $placement = Placement::get()->find('MemberID', $this->owner->ID);
        return ($placement) ? $placement->TotalGroupDownline : 0;
    }
	
	function getTotalPlacementLeftGroupDownline(){
        $placement = Placement::get()->find('MemberID', $this->owner->ID);
        return ($placement) ? $placement->TotalLeftGroupDownline : 0;
    }
	
	function getTotalPlacementRightGroupDownline(){
        $placement = Placement::get()->find('MemberID', $this->owner->ID);
        return ($placement) ? $placement->TotalRightGroupDownline : 0;
    }
	
	public function providePermissions() {
        return array(
            'CHANGE_Placement' => array(
                'name' => _t('AddPlacement.PERMISSION_CHANGE_PLACEMENT', 'Allow change placement'),
                'category' => _t('AddPlacement.PERMISSIONS_CATEGORY', 'Network')
            )
        );
    }
}
